package com.zuxia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zuxia.code.Code;
import com.zuxia.dto.DumpDto;
import com.zuxia.dto.OrderToDto;
import com.zuxia.dto.OrdersDto;
import com.zuxia.dto.ShopReleaseDto;
import com.zuxia.entity.*;
import com.zuxia.exception.ZuxiaBusinessException;
import com.zuxia.mapper.OrderMapper;
import com.zuxia.mapper.OrdersMapper;
import com.zuxia.param.OrderNextParam;
import com.zuxia.param.OrderPageParam;
import com.zuxia.param.OrderParam;
import com.zuxia.payment.PayOpenFeginApi;
import com.zuxia.rabbit.produce.OrderSender;
import com.zuxia.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zuxia.shop.ShopOpenFeignApi;
import com.zuxia.user.UserOpenFeignApi;
import com.zuxia.utils.*;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.rmi.CORBA.Util;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author laoli
 * @since 2024-11-18
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private ShopOpenFeignApi shopOpenFeignApi;
    @Resource
    private UserOpenFeignApi userOpenFeignApi;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private PayOpenFeginApi payOpenFeginApi;
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Override
    public String partStarTakeOrder(OrderParam orderParam) {
        //商品查询+拼团查询
        R shopReleaseById = shopOpenFeignApi.getShopReleaseById(orderParam.getGroupId());
        if (!shopReleaseById.getSuccess()){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_RELEASE_NOT);
        }
        ShopReleaseDto shopReleaseDto = BeanUtil.copyProperties(shopReleaseById.getData().get("shop-release-single"), ShopReleaseDto.class);
        if(shopReleaseDto.getGroupNum()==getGroupByOrderStatusSuccessCount(orderParam.getGroupId())){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_OVER);
        }
        //拼团点查询
        R dumpById = userOpenFeignApi.getDumpById(orderParam.getDumpId());
        if(!dumpById.getSuccess()){
            throw new ZuxiaBusinessException(ResultCodeEnum.DUMP_IS_NULL);
        }
        DumpDto dumpDto = BeanUtil.copyProperties(dumpById.getData().get("dump-single"), DumpDto.class);
        BigDecimal price = shopReleaseDto.getGroupPrice().multiply(new BigDecimal(orderParam.getNum()));//金额
        String orderId= "TF-"+IdUtil.getSnowflakeNextId();//订单编号
        String time=TimeUtils.getY_M_D_H_M_S(System.currentTimeMillis());//当前时间

        //订单
        Order order = BeanUtil.toBean(shopReleaseDto, Order.class);
        order.setOrderId(orderId);
        order.setDumpId(orderParam.getDumpId());
        order.setUserName(dumpDto.getUserName());
        order.setUserPhone(dumpDto.getUserPhone());
        order.setCommunityName(dumpDto.getCommunityName());
        order.setGroupId(orderParam.getGroupId());
        order.setGroupStarTime(time);
        order.setGroupCondition(shopReleaseDto.getGroupCondition());
        order.setKickBack(shopReleaseDto.getKickBack());

        //订单详情
        Orders orders = new Orders();
        JwtInfo jwtInfo = JwtUtils.jwtInfo;
        orders.setUserId(jwtInfo.getId());
        orders.setUserName(jwtInfo.getNickname());
        orders.setOrdersId("TY-"+IdUtil.getSnowflakeNextId());
        orders.setOrderId(orderId);
        orders.setOrdersPlaceTime(time);
        orders.setShopNum(orderParam.getNum());
        orders.setOrdersPrice(price);
        String payment = payment(orders.getOrdersId(), Float.valueOf(price.toString()));

        if(payment!=null&&!payment.isEmpty()){
            try {
                orderMapper.insert(order);
                ordersMapper.insert(orders);
                Map<String, String> group = new HashMap<>();
                group.put("group",shopReleaseDto.getGroupId());
                System.out.println("--------------->"+shopReleaseDto.getGroupTime());
                int timer=shopReleaseDto.getGroupTime()*1000;
                rabbitTemplate.convertAndSend("delay_ex_group", "group", orderId, new MessagePostProcessor() {
                    @Override
                    public org.springframework.amqp.core.Message postProcessMessage(org.springframework.amqp.core.Message message) throws AmqpException {
                        message.getMessageProperties().setExpiration(timer+"");
                        return message;
                    }
                });
                return payment;
            }catch (Exception e){
                throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_EROEE);
            }
        }else {
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_EROEE);
        }

    }

    @Override
    public String partNextTakeOrder(OrderNextParam nextParam) {
        Order order = orderMapper.selectById(nextParam.getOrderId());
        if (order==null){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_RELEASE_NOT);
        }
        if(order.getOrderStatus()==1){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_OVER);
        }
        LambdaQueryWrapper<Orders> in = new LambdaQueryWrapper<Orders>().eq(Orders::getOrderId, nextParam.getOrderId()).eq(Orders::getUserId, JwtUtils.id);
        Orders ordersed = ordersMapper.selectOne(in.in(Orders::getOrdersStatus, Arrays.asList(0, 1)));

        if(ordersed!=null){
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDER_GROUP_IS_NOTNULL);
        }
        //商品查询+拼团查询
        R shopReleaseById = shopOpenFeignApi.getShopReleaseById(order.getGroupId());
        if (!shopReleaseById.getSuccess()){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_RELEASE_NOT);
        }
        ShopReleaseDto shopReleaseDto = BeanUtil.copyProperties(shopReleaseById.getData().get("shop-release-single"), ShopReleaseDto.class);
        int ordersShopNumById = getOrdersShopNumById(nextParam.getOrderId());
        if(shopReleaseDto.getGroupCondition()<ordersShopNumById+nextParam.getNum()){
            throw new ZuxiaBusinessException(ResultCodeEnum.SHOP_NUMBER_IS_EXCEED);
        }


        BigDecimal price = shopReleaseDto.getGroupPrice().multiply(new BigDecimal(nextParam.getNum()));//金额
        String time=TimeUtils.getY_M_D_H_M_S(System.currentTimeMillis());//当前时间
        //订单详情
        Orders orders = new Orders();
        JwtInfo jwtInfo = JwtUtils.jwtInfo;
        orders.setUserId(jwtInfo.getId());
        orders.setUserName(jwtInfo.getNickname());
        orders.setOrdersId("TY-"+IdUtil.getSnowflakeNextId());
        orders.setOrderId(nextParam.getOrderId());
        orders.setOrdersPlaceTime(time);
        orders.setShopNum(nextParam.getNum());
        orders.setOrdersPrice(price);

        String payment = payment(orders.getOrdersId(), Float.valueOf(price.toString()));
        if(payment!=null&&!payment.isEmpty()){
            if(ordersMapper.insert(orders)==0){
                throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_EROEE);
            }else {
                return payment;
            }
        }else {
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_EROEE);
        }
    }

    @Override
    public PageDto<OrderToDto> getOrdersByUserIdPageList(OrderPageParam orderPageParam) {
        String sql="select * from  `order` b right join orders a on a.order_id=b.order_id where a.user_id='"+JwtUtils.id+"'";
        if(orderPageParam.getStatus()>=0){
            sql+=" and a.orders_status="+orderPageParam.getStatus();
        }
        IPage<OrderToDto> ordersPageList = ordersMapper.getOrdersPageList(new Page(orderPageParam.getPage(), orderPageParam.getSize()), sql);
        List<OrderToDto> records = ordersPageList.getRecords();
        PageDto<OrderToDto> orderToDtoPageDto = new PageDto<>();
        orderToDtoPageDto.setList(records);
        orderToDtoPageDto.setTotal(ordersPageList.getTotal());
        return orderToDtoPageDto;
    }

    @Override
    public int getGroupByOrderStatusSuccessCount(String groupId) {
        LambdaQueryWrapper<Order> orderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderLambdaQueryWrapper.eq(Order::getGroupId, groupId).eq(Order::getOrderStatus,1);
        try {
            return orderMapper.selectCount(orderLambdaQueryWrapper);
        }catch (Exception e){
            return 0;
        }
    }

    @Override
    public boolean upOrdersStatusById(String id, Integer status) {
        Orders orders = new Orders();
        orders.setOrdersId(id);
        orders.setOrdersStatus(status);
        if(ordersMapper.updateById(orders) > 0){
            if(status==2){
                redisUtils.delString(redisUtils.getZFB_URL_Key()+id);
                return true;
            }
        }else {
            if(status==2){
                throw new ZuxiaBusinessException(ResultCodeEnum.ORDER_GROUP_CANCEL);
            }
        }
        return false;
    }

    @Override
    public boolean upOrderStatusById(String id, Integer status) {
        Order order = new Order();
        order.setOrderId(id);
        order.setOrderStatus(status);
        return orderMapper.updateById(order) > 0;
    }

    @Override
    public boolean submit(Orders orders) {
        OrderToDto orderOnOrdersById = getOrderOnOrdersById(orders.getOrdersId());
        Order orderById = getOrderById(orderOnOrdersById.getOrderId());
        if(orderById.getOrderStatus()==3){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_OVER1);
        }
        if(orderOnOrdersById==null){
            throw new ZuxiaBusinessException(ResultCodeEnum.SUBMIT_ORRDERS_IS_NULL);
        }
        if(orderOnOrdersById.getOrdersStatus()==1){
            throw new ZuxiaBusinessException(ResultCodeEnum.SUBMIT_IS_NOTNULL);
        }
        if(orderOnOrdersById.getOrdersStatus()==0){
            if(orderOnOrdersById.getGroupCondition()==orderOnOrdersById.getShopNum()){
                Order order = new Order();
                order.setOrderId(orderOnOrdersById.getOrderId());
                order.setOrderStatus(orders.getOrdersStatus());
                order.setGroupEndTime(TimeUtils.getY_M_D_H_M_S(System.currentTimeMillis()));
                updateById(order);
                shopOpenFeignApi.upGroupSuccessNum(orderOnOrdersById.getGroupId(),1);
            }else {
                int num=0;
                try {
                    num = ordersMapper.getOrdersShopSusseceNumBy(orderOnOrdersById.getOrderId());
                }catch (Exception e){
                    num=0;
                }
                if (orderOnOrdersById.getShopNum()+num==orderOnOrdersById.getGroupCondition()){
                    Order order = new Order();
                    order.setOrderId(orderOnOrdersById.getOrderId());
                    order.setOrderStatus(orders.getOrdersStatus());
                    order.setGroupEndTime(TimeUtils.getY_M_D_H_M_S(System.currentTimeMillis()));
                    updateById(order);
                    shopOpenFeignApi.upGroupSuccessNum(orderOnOrdersById.getGroupId(),1);
                }
            }
            redisUtils.delString(redisUtils.getZFB_URL_Key()+orders.getOrdersId());
        }else {
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_SUBMIT_FALSE);
        }

        return ordersMapper.updateById(orders)>0;
    }

    @Override
    public PageDto<Order> getOrderPageList(OrderPageParam param) {
        Page<Order> orderPage = orderMapper.selectPage(new Page<>(param.getPage(), param.getSize()), new LambdaQueryWrapper<Order>().eq(Order::getOrderStatus, param.getStatus()));
        PageDto<Order> orderPageDto = new PageDto<>();
        orderPageDto.setTotal(orderPage.getTotal());
        orderPageDto.setList(orderPage.getRecords());
        return orderPageDto;
    }

    @Override
    public int getCountMemberByOrderId(String orderId) {
        return ordersMapper.selectCount(new LambdaQueryWrapper<Orders>().eq(Orders::getOrderId,orderId).in(Orders::getOrdersStatus,Arrays.asList(0, 1)));
    }

    @Override
    public int getOrdersShopNumById(String orderId) {
        try {
            int ordersShopNumById = ordersMapper.getOrdersShopNumById(orderId);
            return ordersShopNumById;
        }catch (Exception e){
            return 0;
        }
    }

    @Override
    public Order getOrderById(String orderId) {
        Order order = orderMapper.selectById(orderId);
        if(order==null){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_RELEASE_NOT);
        }
        return order;
    }

    @Override
    public OrdersDto getOrderOnOrdersById(String orderId,Integer status) {
        OrdersDto ordersDto = BeanUtil.copyProperties(getOrderById(orderId), OrdersDto.class);
        //商品查询+拼团查询
        R shopReleaseById = shopOpenFeignApi.getShopReleaseById(ordersDto.getGroupId());
        if (!shopReleaseById.getSuccess()){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_IS_RELEASE_NOT);
        }
        ShopReleaseDto shopReleaseDto = BeanUtil.copyProperties(shopReleaseById.getData().get("shop-release-single"), ShopReleaseDto.class);
        ordersDto.setGroupCondition(shopReleaseDto.getGroupCondition());
        ordersDto.setGroupSuccessNum(shopReleaseDto.getGroupSuccessNum());
        ordersDto.setGroupNum(shopReleaseDto.getGroupNum());
        ordersDto.setGroupTime(shopReleaseDto.getGroupTime());
        List<Orders> ordersList = ordersMapper.selectList(new LambdaQueryWrapper<Orders>().eq(Orders::getOrderId, orderId).eq(Orders::getOrdersStatus,status));
        List<com.zuxia.entity.order.Orders> orders = BeanUtil.copyToList(ordersList, com.zuxia.entity.order.Orders.class);

        ordersDto.setOrders(BeanUtil.copyToList(ordersList, com.zuxia.entity.order.Orders.class));
        return ordersDto;
    }

    @Override
    public Orders getOrdersById(String ordersId) {
        Orders orders = ordersMapper.selectById(ordersId);
        if (orders==null){
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_IS_NULL);
        }
        return orders;
    }

    @Override
    public String payment(String ordersId) {
        Orders orders = ordersMapper.selectById(ordersId);
        if(orders==null){
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_IS_NULL);
        }
        if(orders.getOrdersStatus()==1){
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_STATUS_1);
        }
        String from = redisUtils.getString(redisUtils.getZFB_URL_Key() + ordersId);
        System.out.println(from);
        if(from==null){
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_SUBMIT_FALSE);
        }
        return from;
    }

    @Override
    public OrderToDto getOrderOnOrdersById(String ordersId){
        return orderMapper.getOrderOnOrdersById(ordersId);
    }

    @Override
    public boolean sendShop(String orderId) {
        Order orderById = getOrderById(orderId);
        System.out.println(orderById.getOrderStatus());
        if(orderById.getOrderStatus()==0){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_SEND_SHOP);
        }
        if(orderById.getOrderStatus()==Code.SEND_SHOP.getCode()){
            throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_SEND_SHOP_FALSE);
        }
        if(orderById.getOrderStatus()==1){
            boolean b = upOrderStatusById(orderId, Code.SEND_SHOP.getCode());
            if(b){
                LambdaUpdateWrapper<Orders> wrapper = new LambdaUpdateWrapper<>();
                wrapper.set(Orders::getOrdersStatus,Code.SEND_SHOP.getCode()).eq(Orders::getOrderId,orderId);
                int update = ordersMapper.update(new Orders(), wrapper);
                if(update<=0){
                    b=false;
                }
            }
            return b;
        }
        throw new ZuxiaBusinessException(ResultCodeEnum.GROUP_SEND_SHOP_IS_ERROR);
    }

    @Override
    public String selectOrderIdById(String ordersId) {
        LambdaQueryWrapper<Orders> ordersLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ordersLambdaQueryWrapper.select(Orders::getOrderId);
        return ordersMapper.selectOne(ordersLambdaQueryWrapper.eq(Orders::getOrdersId,ordersId)).getOrderId();
    }

    private String payment(String ordersId,Float price){
        R payment = payOpenFeginApi.payment(ordersId,price);
        if(!payment.getSuccess()){
            throw new ZuxiaBusinessException(ResultCodeEnum.ORDERS_EROEE);
        }
        String from = payment.getData().get("payment").toString();
        redisUtils.setString(redisUtils.getZFB_URL_Key()+ordersId,from,1000L*60*10);
        Map<String, String> map = new HashMap<>();
        map.put("ordersId",ordersId);
        rabbitTemplate.convertAndSend("delay_ex", "order", map, new MessagePostProcessor() {
            @Override
            public org.springframework.amqp.core.Message postProcessMessage(org.springframework.amqp.core.Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("600000");//600000
                return message;
            }
        });
        return from;
    }

}
